﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using Source.Common;
using Source.ServiceLayer;


namespace Source.ServerSide
{

    public interface IEmailMessageSender
    {

        int Send(EmailMessageTypes messageType, IEnumerable<string> toEmailAddresses, IEnumerable<string> ccEmailAddresses, OrderEmailDetailViewDto order);

    }

    public class EmailMessageSender: IEmailMessageSender
    {

        private readonly IEmailTemplateProvider emailTemplateProvider;
        private readonly IServerSideUserManager userManager;
        private readonly IEmailClientProcessor emailClientProcessor;
        private readonly IConfigurationProvider configurationProvider;

        public EmailMessageSender(IServerSideUserManager userManager, IEmailTemplateProvider emailTemplateProvider, IEmailClientProcessor emailClientProcessor, IConfigurationProvider configurationProvider)
        {
            this.emailTemplateProvider = emailTemplateProvider;
            this.userManager = userManager;
            this.emailClientProcessor = emailClientProcessor;
            this.configurationProvider = configurationProvider;
        }

        public int Send(EmailMessageTypes messageType, IEnumerable<string> toEmailAddresses, IEnumerable<string> ccEmailAddresses, 
            OrderEmailDetailViewDto order)
        {
            string subject = GetEmailSubject(messageType, order);
            string fromAddress = configurationProvider.FromEmailAddress;
            string content = LoadTemplateAndReplaceValues(messageType, order);
            
            IEnumerable<string> allEmailAddressesThatWillReceiveAnEmail = toEmailAddresses.Distinct().ToList();
            IEnumerable<string> allEmailAddressesThatWillReceiveACC = ccEmailAddresses.Distinct().ToList();
            allEmailAddressesThatWillReceiveACC = allEmailAddressesThatWillReceiveACC.Where(a => !allEmailAddressesThatWillReceiveAnEmail.Contains(a));

            emailClientProcessor.ProcessMail(subject, content, fromAddress, allEmailAddressesThatWillReceiveAnEmail, allEmailAddressesThatWillReceiveACC);

            return allEmailAddressesThatWillReceiveAnEmail.Count() + allEmailAddressesThatWillReceiveACC.Count();
        }

        private string GetEmailSubject(EmailMessageTypes messageType, OrderEmailDetailViewDto order)
        {
            string subject = "{0} {1} - {2} - {3} ({4} - {5})";
            return string.Format(subject, order.SubCategoryName, order.OrderId, EmailMessageSubjects.GetSubject(messageType), order.CustomerName, order.CustomerId, order.CustomerCountry);
        }

        private string LoadTemplateAndReplaceValues(EmailMessageTypes type, OrderEmailDetailViewDto order)
        {
            string templateContent = emailTemplateProvider.LoadTemplate(type.ToString());
            return ReplaceParameterValues(templateContent, order);
        }

        private string ReplaceParameterValues(string content, OrderEmailDetailViewDto order)
        {
            content = ReplaceParameterValue(content, "orderId", order.OrderId);
            content = ReplaceParameterValue(content, "customerName", order.CustomerName);
            content = ReplaceParameterValue(content, "customerId", order.CustomerId);
            content = ReplaceParameterValue(content, "customerCountry", order.CustomerCountry);
            content = ReplaceParameterValue(content, "sellingUnit", order.SellingEntityName);
            content = ReplaceParameterValue(content, "currentDate", DateTimeProvider.Now.ToString(GlobalConstants.supportedDateTimeFormats[0] + " HH:mm")); // this date format is fixed
            content = ReplaceParameterValue(content, "creator", order.CreatorName);
            content = ReplaceParameterValue(content, "orderStatus", order.OrderStatus);
            content = ReplaceParameterValue(content, "requester", order.RequesterName);
            content = ReplaceParameterValue(content, "hyperlinkToOrder", CreateLinkToOrder(order));
            content = ReplaceParameterValue(content, "subCategory", order.SubCategoryName);
            content = ReplaceParameterValue(content, "rsmType", order.RsmTypeName ?? "");

            if(userManager.HasVisit())
            {
                content = ReplaceParameterValue(content, "currentUser", userManager.GetCurrentUserInfo().FirstName + " " + userManager.GetCurrentUserInfo().LastName);
            }
            else
            {
                content = ReplaceParameterValue(content, "currentUser", "");
            }
            

            return content;
        }

        private string ReplaceParameterValue(string content, string parameterName, object replacementValue)
        {
            return content.Replace("<%" + parameterName + "%>", replacementValue == null? "" : replacementValue.ToString());
        }

        private string CreateLinkToOrder(OrderEmailDetailViewDto order)
        {
            return string.Format("{0}?{1}={2}", configurationProvider.OpenOrderLink, QuerystringParameterKeys.OrderId, order.OrderId); 
        }

    }

    public class OrderEmailDetailViewDto
    {
        public string OrderStatus
        { get; set; }

        public int OrderId
        { get; set; }

        public int OrderStatusId
        { get; set; }
        public bool InvolveRequester
        { get; set; }

        public string CreatorName
        { get; set; }

        public string CreatorEmail
        { get; set; }

        public string RequesterName
        { get; set; }

        public string RequesterEmail
        { get; set; }

        public string SubCategoryName
        { get; set; }

        public string RsmTypeName
        { get; set; }

        public string CustomerId
        { get; set; }

        public string CustomerName
        { get; set; }


        public long LegalUnitId
        { get; set; }

        public string SellingEntityName
        { get; set; }
        public string CustomerCountry
        { get; set; }
    }
}
